package mcommand;

import java.util.ArrayList;
import java.util.Collections;

/**
 * Handles how to add, refresh, and sort the highscore.
 *
 * @author Marcel, Christian, Klaus
 *
 */
public class Highscore {

    // defines a variabel for a ArrayList with HighscoreUnits
    private ArrayList<HighscoreUnit> highscoreUnits;
    private int maxHighscoreEntries = 10;

    /**
     * Creates a new Arraylist with highscore units and loads the XML highscore
     * data into it.
     *
     * @param autoRefresh autoRefresh
     */
    public Highscore(final boolean autoRefresh) {
        // creates a new ArrayList for the highscore units
        highscoreUnits = new ArrayList<HighscoreUnit>();

        // calls the refresh method to loads the highscore data
        // from the XML into the ArrayList
        if (autoRefresh) {
            refresh();
        } else {
            highscoreUnits = new ArrayList<HighscoreUnit>();
        }
    }

    /**
     * Adds to highscore if its placed in the first 10.
     * 
     * @param newUnit newUnit
     * @return returns the place of the newUnit
     */
    public final int addHighscore(final HighscoreUnit newUnit) {
        // refreshes;
        refresh();

        // if the highscore is smaller than the max entries
        if (highscoreUnits.size() < maxHighscoreEntries) {

            // adds it
            highscoreUnits.add(newUnit);

            // calls the sort method
            sortHighscore();

            // if the highscore has 10 entries
        } else {

            // for every entry in the highscore
            for (int i = (highscoreUnits.size() - 1); i >= 0; i--) {

                // checks if the current new score is bigger
                // than the actual entry
                if (newUnit.score > highscoreUnits.get(i).score) {

                    // if its bigger than the current entry, it adds
                    // the score before the smalle score
                    highscoreUnits.add(newUnit);

                    // if we are in debug mode, a message is printed
                    // out that the value was added to the highscore
                    if (Board.DEBUG) {
                        System.out.println("Highscore "
                                + "- Hat es auf Highscore geschafft.");
                    }

                    // calls the sort method
                    sortHighscore();

                    // removes the last entry in the highscore, so
                    // that it wouldn't become more than 10 entries
                    highscoreUnits.remove(highscoreUnits.size() - 1);

                    break;
                }
            }
        }

        // prints out the highscore list size
        if (Board.DEBUG) {
            System.out.println("Highscore Laenge: " + highscoreUnits.size());
        }

        // creates new ArrayList for playernames and scores
        ArrayList<String> playernames = new ArrayList<String>();
        ArrayList<Integer> scores = new ArrayList<Integer>();

        // for every entry in the highscoreUnits
        for (int i = 0; i < highscoreUnits.size(); i++) {
            // splits the highscoreUnits in units
            HighscoreUnit unit = highscoreUnits.get(i);

            // and add the playernames and the score in separate ArrayLists
            playernames.add(unit.playername);
            scores.add(unit.score);
        }

        // writes a highscore XML file
        ToolXMLWriter.writeHighscore(playernames, scores);

        // returns the position of the current new score in the highscore
        return getHighscorePosition(newUnit);
    }

    /**
     * For the junit test, adds highscore if its placed in the first 10.
     * 
     * @param newUnit newUnit
     * @return returns the place of the newUnit
     */
    public final int addHighscoreTest(final HighscoreUnit newUnit) {
        if (highscoreUnits.size() < maxHighscoreEntries) {
            highscoreUnits.add(newUnit);
            sortHighscore();
        } else {
            for (int i = (highscoreUnits.size() - 1); i >= 0; i--) {
                if (newUnit.score > highscoreUnits.get(i).score) {
                    highscoreUnits.add(newUnit);

                    if (Board.DEBUG) {
                        System.out.println("Highscore - "
                                + "Hat es auf Highscore geschafft.");
                    }

                    sortHighscore();
                    highscoreUnits.remove(highscoreUnits.size() - 1);

                    break;
                }
            }
        }
        return getHighscorePosition(newUnit);
    }

    /**
     * Sorts the highscore. If the debug mode is on a message is printed out if
     * it's finished.
     */
    private void sortHighscore() {
        Collections.sort(highscoreUnits);

        if (Board.DEBUG) {
            System.out.println("Highscore Sortiert");
        }
    }

    /**
     * Please refresh() before this method please! Return then the highscore.
     * 
     * @return highscoreUnits
     */
    public final ArrayList<HighscoreUnit> getHighscore() {
        return highscoreUnits;
    }

    /**
     * Returns the highscore position of the highscore unit.
     * 
     * @param unit unit
     * @return 0 or position
     */
    public final int getHighscorePosition(final HighscoreUnit unit) {
        int result = 0;
        if ((result = highscoreUnits.indexOf(unit)) != -1) {
            return (result + 1);
        } else {
            return 0;
        }
    }

    /**
     * Reads the highscore from the XML file. And then calls the sortHighscore
     * method.
     */
    public final void refresh() {
        ToolXMLReader xmlreader = new ToolXMLReader();
        highscoreUnits = xmlreader.readHighscoreFromXML();
        sortHighscore();
    }
}
